package entity

import (
	"src/zeus/iserver"
	"src/zeus/logger"
	"sync"
)

var _ iserver.ICallInfo = &callbackInfo{}

func NewCommonCallInfo(cb func()) iserver.ICallInfo {
	return &callbackInfo{
		cb: cb,
	}
}

type callbackInfo struct {
	cb func()
}

func (c *callbackInfo) Exec() {
	defer func() {
		c.cb = nil
	}()
	c.cb()
}

func NewDelayCallHandle(size int) iserver.IDelayCallHandle {
	return &callDelayHandle{
		delayCallChan: make([]iserver.ICallInfo, 0, size),
		excelList:     make([]iserver.ICallInfo, 0, size),
	}
}

type callDelayHandle struct {
	delayCallChan, excelList []iserver.ICallInfo
	lock                     sync.Mutex
}

func (c *callDelayHandle) ClearAllData() {
	c.excelList = nil
	c.delayCallChan = nil
}
func (c *callDelayHandle) CallDelay(cb func()) error {
	c.lock.Lock()
	defer c.lock.Unlock()

	c.delayCallChan = append(c.delayCallChan, NewCommonCallInfo(cb))
	return nil
}
func (c *callDelayHandle) CallDelayExec2() {
	execList := c.delayCallChan
	c.delayCallChan = make([]iserver.ICallInfo, 0)
	for _, v := range execList {
		v.Exec()
	}
}

func (c *callDelayHandle) CallDelayExec() {
	// execList := c.getTasks()
	// for _, v := range execList {
	// 	v.Exec()
	// }
	/*
		修改缓存的方式。避免重复申请
	*/
	execList := c.swapTaskList()
	defer func() {
		// clear(c.excelList)
		c.excelList = execList[0:0]
	}()
	for _, v := range execList {
		v.Exec()
	}

}

func (c *callDelayHandle) swapTaskList() (result []iserver.ICallInfo) {
	c.lock.Lock()
	defer c.lock.Unlock()
	result = c.delayCallChan
	//清空上次执行的队列 并赋值给下次要进行的延迟队列
	// clear(c.excelList)
	c.delayCallChan = c.excelList[:0]
	c.excelList = result
	return result
	// c.delayCallChan, c.excelList = c.excelList[0:0], c.delayCallChan
	// return c.excelList
}

func (c *callDelayHandle) Len() int {
	return len(c.delayCallChan)
}

// func (c *callDelayHandle) getTasks() (result []iserver.ICallInfo) {
// 	c.lock.Lock()
// 	defer c.lock.Unlock()
// 	// execList := []iserver.ICallInfo{}
// 	listLen := len(c.delayCallChan)
// 	// execLen := listLen
// 	// if listLen > 100 {
// 	// 	result = c.delayCallChan[:100]
// 	// 	c.delayCallChan = c.delayCallChan[100:]
// 	// 	// execLen = 100
// 	// 	// execList := make([]iserver.ICallInfo, 0, execLen)
// 	// 	// copy(execList, c.delayCallChan[:execLen+1])
// 	// 	// c.delayCallChan = append([]iserver.ICallInfo{}, c.delayCallChan[100:]...)
// 	// } else
// 	if listLen > 0 {
// 		result = c.delayCallChan
// 		c.delayCallChan = make([]iserver.ICallInfo, 0, 100)
// 		// execList := make([]iserver.ICallInfo, 0, listLen)
// 		// copy(execList, c.delayCallChan)
// 		// c.delayCallChan = c.delayCallChan[0:0]
// 	}
// 	return
// }

// func (c *callDelayHandle) GetDelayCallChan() <-chan iserver.ICallInfo {
// 	return c.delayCallChan
// }

func (c *callDelayHandle) OnDestroyCallDelayHandle() {
	c.lock.Lock()
	defer c.lock.Unlock()
	c.delayCallChan = nil

	// delayCallChan := c.delayCallChan
	// c.delayCallChan = nil
	// if delayCallChan != nil {
	// 	close(delayCallChan)
	// }
}

type DelayCallHost struct {
	// lock            sync.RWMutex
	delayCallHandle iserver.IDelayCallHandle
}

func (s *DelayCallHost) CallDelay(cb func()) error {
	// s.lock.Lock()
	// defer s.lock.Unlock()
	if s.delayCallHandle != nil {
		return s.delayCallHandle.CallDelay(cb)
	}

	cb()
	logger.Warn("delayCallHandle is nil while CallDelay")
	return nil
}

func (s *DelayCallHost) SetDelayCallHandle(imp iserver.IDelayCallHandle) {
	// s.lock.Lock()
	// defer s.lock.Unlock()
	s.delayCallHandle = imp
}

func (s *DelayCallHost) GetDelayCallHandle() iserver.IDelayCallHandle {
	return s.delayCallHandle
}

func (s *DelayCallHost) ClearAllData() {
	if s.delayCallHandle != nil {
		s.delayCallHandle.ClearAllData()
	}
}

// 加上等待
func (s *DelayCallHost) CallDelayWait(cb func()) error {
	gp := new(sync.WaitGroup)
	gp.Add(1)
	s.CallDelay(func() {
		defer gp.Done()
		cb()
	})
	gp.Wait()
	return nil
}
